package com.douziit.meilianoa.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.douziit.meilianoa.base.annotation.NoCheckToken;
import com.douziit.meilianoa.base.exception.TipException;
import com.douziit.meilianoa.base.request.PageRequest;
import com.douziit.meilianoa.base.response.ResponseData;
import com.douziit.meilianoa.base.response.ResponseUtil;
import com.douziit.meilianoa.base.utils.ExportExcel;
import com.douziit.meilianoa.dto.ButtenInfo;
import com.douziit.meilianoa.dto.ProjectListInfo;
import com.douziit.meilianoa.entity.*;
import com.douziit.meilianoa.service.*;
import lombok.extern.slf4j.Slf4j;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 项目信息控制类
 */

@Slf4j
@RestController
@RequestMapping("/project")
public class ProjectInfoController {


    @Autowired
    private ProjectInfoService projectInfoService;

    @Autowired
    private TargetAmountService targetAmountService;

    @Autowired
    private FeesService feesService;

    @Autowired
    private ProjectEvalutionService projectEvalutionService;

    @Autowired
    private InvoiceService invoiceService;

    @Autowired
    private AccountService accountService;

    /**
     * 添加项目
     */
    @PostMapping("/addProject")
    public ResponseData addProject(@RequestBody ProjectInfo projectInfo){

        ProjectInfo p = projectInfoService.getOne(new QueryWrapper<ProjectInfo>().eq("project_no",projectInfo.getProjectNo()));
        if(p != null){
            throw new TipException("此项目编号已存在!");
        }
        Account account = accountService.findUserInfoByToken();
        projectInfo.setCreatorId(account.getId());
        projectInfo.setStatus(0);
        projectInfoService.save(projectInfo);
        return ResponseUtil.jsonSuccess(0);
    }

    /**
     * 修改项目信息
     */
    @PostMapping("/changeProject")
    public ResponseData changeProject(@RequestBody ProjectInfo projectInfo){

        ProjectInfo projectInfo1=projectInfoService.getById(projectInfo.getId());
        if (!projectInfo1.getStatus().equals(0)&&!projectInfo1.getStatus().equals(1)&&!projectInfo1.getStatus().equals(2)){
            throw new TipException("已审批不可修改");
        }
        Account account = accountService.findUserInfoByToken();
        if(!account.getId().equals(projectInfo1.getCreatorId())){
            throw new TipException("无修改权限");
        }
        projectInfoService.updateById(projectInfo);
        return ResponseUtil.jsonSuccess(0);
    }


    /**
     * pc项目列表
     * 传值status:0/null:全部 1:待申请预算 2:待审批预算 3:已审批预算
     * status:   '0：待申请 1：待审批预算 2：预算未通过 3：待报销  4：待审批报销 5：已报销 6：报销未通过'
     * orderFlag 排序方式 状态值   0:计划时间顺序 1:计划时间倒序 2:主督导顺序 3:主督导倒序 4:预算毛利率顺序 5:预算毛利率倒序
     * role : 0：超管 1：管理员 2：财务 3：督导
     */
    @PostMapping("/listProjectPc")
    public ResponseData listProjectPc(@RequestBody PageRequest req){

        List<ProjectListInfo> projectListInfos=projectInfoService.selProjectInfoPc(req);
        Map<String , Object> map = new HashMap<>();
        map.put("data",projectListInfos);
        map.put("total",projectListInfos.size());
        return ResponseUtil.jsonSuccess(map);
    }

    /**
     * pc项目列表
     * 传值status:0/null:全部 1:待申请预算 2:待审批预算 3:已审批预算
     * status:   '0：待申请 1：待审批预算 2：预算未通过 3：待报销  4：待审批报销 5：已报销 6：报销未通过'
     * orderFlag 排序方式 状态值   0:计划时间顺序 1:计划时间倒序 2:主督导顺序 3:主督导倒序 4:预算毛利率顺序 5:预算毛利率倒序
     * role : 0：超管 1：管理员 2：财务 3：督导
     */
    @PostMapping("/listProjectApp")
    public ResponseData listProjectApp(@RequestBody PageRequest req){

        List<ProjectListInfo> projectListInfos=projectInfoService.selProjectInfoApp(req);
        Map<String , Object> map = new HashMap<>();
        map.put("data",projectListInfos);
        map.put("total",projectListInfos.size());
        return ResponseUtil.jsonSuccess(map);
    }

    /**
     * 项目详情
     */
    @PostMapping("/projectDetail/{projectId}")
    public ResponseData projectDetail(@PathVariable("projectId") Integer projectId){
        ProjectListInfo projectListInfo = projectInfoService.selProjectDetail(projectId);
        return ResponseUtil.jsonSuccess(projectListInfo);
    }

    /**
     * 批量导出项目信息
     */
    @PostMapping("/exportProjectInfo")
    public ResponseData exportProjectInfo(HttpServletResponse response,@RequestBody PageRequest req){
        List<ProjectListInfo> projectListInfos=projectInfoService.selProjectInfoPc(req);
        String title = "项目信息导出表";
        String[] rowsName = new String[]{"项目编号","项目名称","项目状态","客户名称","客户项目号","联系人","联系电话","执行城市","执行方式","主样本量","备注","样本备量","备注",
                                        "计划开始日期","计划结束日期","主控督导","所占比例","协同督导","所占比例","项目费用","访问员费用","备注","联络员费用","备注","拦截员费用",
                                        "备注","兼职费用","备注","场地费用","备注","受访者费用","备注","礼品费用","备注","交通费用","备注","差差旅费用","备注","出差补助","备注",
                                        "问卷费用","备注","其他费用","备注","预算总计","预算毛利","预算毛利率","借款","访问员费用","备注","联络员费用","备注","拦截员费用","备注"
                                        ,"兼职费用","备注","场地费用","备注","受访者费用","备注","礼品费用","备注","交通费用","备注","差差旅费用","备注","出差补助","备注","问卷费用",
                                        "备注","其他费用","备注","总计","预算总计","预决比","最终毛利率","最终毛利","借款","退款金额","项目评价","其他意见","第一次开票时间","金额","备注",
                                        "回款时间","备注","第二次开票时间","金额","备注","回款时间","备注","第三次开票时间","金额","备注","回款时间","备注"};
        List<Object[]>  dataList = new ArrayList<Object[]>();
        Object[] objs = null;
        SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < projectListInfos.size(); i++) {
            ProjectListInfo project = projectListInfos.get(i);
            objs = new Object[rowsName.length];
            objs[0]=project.getProjectNo();
            objs[1]=project.getName();
            switch (project.getStatus()){
                case 0:
                case 2:objs[2]="待申请预算";break;
                case 1:objs[2]="待审批预算";break;
                case 3:
                case 5:
                case 6:
                case 4:objs[2]="已审批预算";break;
            }
            objs[3]=project.getCustomer();
            objs[4]=project.getCustomerProNo();
            objs[5]=project.getContact();
            objs[6]=project.getLinkPhone();
            objs[7]=project.getCity();
            objs[8]=project.getExecuteType();
            objs[9]=project.getMainSampleSize();
            objs[10]=project.getMainRemark();
            objs[11]=project.getAuxiliarySampleSize();
            objs[12]=project.getAuxiliaryRemark();
            objs[13]=sdf.format(project.getStartTime());
            objs[14]=sdf.format(project.getEndTime());
            objs[15]=project.getAccount();
            objs[16]=project.getAccountRate()+"%";
            objs[17]=project.getAuxiliary_account();
            objs[18]=(100.00-project.getAccountRate())+"%";
            objs[19]=project.getAmount();
            if(project.getBugFees()!=null){
                objs[20]=project.getBugFees().getVistorFee();
                objs[21]=project.getBugFees().getVistorRemark();
                objs[22]=project.getBugFees().getLiaisonFee();
                objs[23]=project.getBugFees().getLiaisonRemark();
                objs[24]=project.getBugFees().getInterceptorFee();
                objs[25]=project.getBugFees().getInterceptorRemark();
                objs[26]=project.getBugFees().getPartTimeFee();
                objs[27]=project.getBugFees().getPartTimeRemark();
                objs[28]=project.getBugFees().getSiteFee();
                objs[29]=project.getBugFees().getSiteRemark();
                objs[30]=project.getBugFees().getIntervieweeFee();
                objs[31]=project.getBugFees().getInterceptorRemark();
                objs[32]=project.getBugFees().getGiftFee();
                objs[33]=project.getBugFees().getGiftRemark();
                objs[34]=project.getBugFees().getTransportationFee();
                objs[35]=project.getBugFees().getTransportationRemark();
                objs[36]=project.getBugFees().getTravelFee();
                objs[37]=project.getBugFees().getTravelRemark();
                objs[38]=project.getBugFees().getTravelAllowance();
                objs[39]=project.getBugFees().getTravelNote();
                objs[40]=project.getBugFees().getQuestionnaireFee();
                objs[41]=project.getBugFees().getQuestionnaireRemark();
                objs[42]=project.getBugFees().getOtherFee();
                objs[43]=project.getBugFees().getOtherRremark();
                objs[44]=project.getBugFees().getTotalFee();
                objs[45]=project.getBugFees().getGrossPorfit();
                objs[46]=project.getBugFees().getRate();
                objs[47]=project.getBugFees().getLoan();
            }

            if(project.getReiFees()!=null){
                objs[48]=project.getReiFees().getVistorFee();
                objs[49]=project.getReiFees().getVistorRemark();
                objs[50]=project.getReiFees().getLiaisonFee();
                objs[51]=project.getReiFees().getLiaisonRemark();
                objs[52]=project.getReiFees().getInterceptorFee();
                objs[53]=project.getReiFees().getInterceptorRemark();
                objs[54]=project.getReiFees().getPartTimeFee();
                objs[55]=project.getReiFees().getPartTimeRemark();
                objs[56]=project.getReiFees().getSiteFee();
                objs[57]=project.getReiFees().getSiteRemark();
                objs[58]=project.getReiFees().getIntervieweeFee();
                objs[59]=project.getReiFees().getInterceptorRemark();
                objs[60]=project.getReiFees().getGiftFee();
                objs[61]=project.getReiFees().getGiftRemark();
                objs[62]=project.getReiFees().getTransportationFee();
                objs[63]=project.getReiFees().getTransportationRemark();
                objs[64]=project.getReiFees().getTravelFee();
                objs[65]=project.getReiFees().getTravelRemark();
                objs[66]=project.getReiFees().getTravelAllowance();
                objs[67]=project.getReiFees().getTravelNote();
                objs[68]=project.getReiFees().getQuestionnaireFee();
                objs[69]=project.getReiFees().getQuestionnaireRemark();
                objs[70]=project.getReiFees().getOtherFee();
                objs[71]=project.getReiFees().getOtherRremark();
                objs[72]=project.getReiFees().getTotalFee();
                objs[73]=project.getBugFees().getTotalFee();
                objs[74]=(project.getReiFees().getTotalFee()/project.getBugFees().getTotalFee())*100;
                objs[75]=project.getReiFees().getGrossPorfit();
                objs[76]=project.getReiFees().getRate();
                objs[77]=project.getBugFees().getLoan();
                objs[78]=project.getReiFees().getRefundAmount();
            }

            objs[79]=project.getScore()+project.getMessage();
            objs[80]=project.getOther();
            if (project.getInvoice().size()>=1){
                objs[81]=sdf.format(project.getInvoice().get(0).getInvoiceTime());
                objs[82]=project.getInvoice().get(0).getAmount();
                objs[83]=project.getInvoice().get(0).getRemark();
                objs[84]=sdf.format(project.getInvoice().get(0).getPaymentCollectionTime());
                objs[85]=project.getInvoice().get(0).getPaymentCollectionRemark();
            }

            if(project.getInvoice().size()>=2){
                objs[86]=sdf.format(project.getInvoice().get(1).getInvoiceTime());
                objs[87]=project.getInvoice().get(1).getAmount();
                objs[88]=project.getInvoice().get(1).getRemark();
                objs[89]=sdf.format(project.getInvoice().get(1).getPaymentCollectionTime());
                objs[90]=project.getInvoice().get(1).getPaymentCollectionRemark();
            }

            if(project.getInvoice().size()>=3){
                objs[91]=sdf.format(project.getInvoice().get(2).getInvoiceTime());
                objs[92]=project.getInvoice().get(2).getAmount();
                objs[93]=project.getInvoice().get(2).getRemark();
                objs[94]=sdf.format(project.getInvoice().get(2).getPaymentCollectionTime());
                objs[95]=project.getInvoice().get(2).getPaymentCollectionRemark();
            }
        }
        ExportExcel ex = new ExportExcel(title, rowsName, dataList);
        try {
            ex.export(response);
        } catch (Exception e) {
            log.info(">>>>>>>>>>>导出excel失败e:{}",e);
            throw new TipException("导出失败");
        }
            return ResponseUtil.jsonSuccess(0);
    }


    /**
     * 项目管理   金额计算
     */
    @GetMapping("/countAmount")
    public ResponseData countAmount(@RequestParam Integer accountId,@RequestParam Integer role){
        SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd");
        String year = sdf.format(new Date()).toString();
        Double tar_total = 0.00;    //目标金额
        Double rel_total = 0.00;    //项目金额贡献
        Double grossPorfit_total = 0.00;    //毛利贡献
        Double rate = 0.00;    //年度项目目标完成率
        Map<String , Double> map = new HashMap<>();
        if(role == 0 || role == 1 || role == 2 ){
            List<TargetAmount> targetAmounts = targetAmountService.list(new QueryWrapper<TargetAmount>()
                                            .eq("target_year",year));
            for(TargetAmount targetAmount : targetAmounts){
                tar_total+=targetAmount.getTargetAmount();
            }
            List<ProjectInfo> projectInfos = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                                            .eq("status",5));
            for (ProjectInfo projectInfo:projectInfos){
                Fees fees= feesService.getOne(new QueryWrapper<Fees>().eq("project_id",projectInfo.getId()));
                rel_total+=fees.getTotalFee();
                grossPorfit_total+=fees.getGrossPorfit();
            }
        }else if(role == 3){
            TargetAmount targetAmount = targetAmountService.getOne(new QueryWrapper<TargetAmount>()
                                            .eq("target_year",year).eq("account_id",accountId));
            if(targetAmount!=null){
                tar_total = targetAmount.getTargetAmount();
            }
            List<ProjectInfo> projectInfos = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                                            .eq("account_id",accountId).eq("status",5));
            for (ProjectInfo projectInfo:projectInfos){
                Fees fees= feesService.getOne(new QueryWrapper<Fees>().eq("project_id",projectInfo.getId()));
                rel_total+=fees.getTotalFee()*fees.getRate();
                grossPorfit_total+=(fees.getGrossPorfit()*fees.getRate());
            }
            List<ProjectInfo> projectInfos1 = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .eq("auxiliary_account_id",accountId).eq("status",5));
            for (ProjectInfo projectInfo:projectInfos1){
                Fees fees= feesService.getOne(new QueryWrapper<Fees>().eq("project_id",projectInfo.getId()));
                rel_total+=(fees.getTotalFee()*(100.00-fees.getRate()));
                grossPorfit_total+=(fees.getGrossPorfit()*(100.00-fees.getRate()));
            }
        }
        if(!tar_total.equals(0.00)) {
            rate = (rel_total / tar_total) * 100.00;
        }else{
            rate=100.00;
        }
        map.put("rel_total",rel_total);
        map.put("grossProfit",grossPorfit_total);
        map.put("rate",rate);
        return ResponseUtil.jsonSuccess(map);
    }

    /**
     * 项目状态数
     */
    @GetMapping("/getProStatusCount")
    public ResponseData getProStatusCount(@RequestParam Integer accountId,@RequestParam Integer role){
        Map<String , Integer> map = new HashMap<>();
        Integer notBudgetNum = 0;    //预算待完成项目数                指待申请预算的项目+待审批预算的项目总和
        Integer budgetNum = 0;    //预算已完成项目数                   指已审批预算的项目总数
        Integer notEvalutionNum = 0;    //未评价项目数                 已审批预算，待评价的项目总数
        Integer evalutuionNum = 0;    //已评价项目数                   已审批预算，且已完成评价的项目总数
        Integer notReimbursementNum = 0;    //报销待完成项目数         已审批预算，待填写报销+待审批报销的项目总数
        Integer reimbursementNum = 0;    //报销已完成项目数            已审批预算，已审批报销的项目总数。
        Integer notInvoiceNum = 0;    //开票未完成项目数               预算已审批的项目，一次都没开过票的项目数。
        Integer invoiceNum = 0;    //开票已完成项目数                  已开过票的项目数。
        Integer notBackNum = 0;    //回款未完成项目数                  已开过票，未确认回款的项目数。
        Integer backNum = 0;    //回款已完成项目数                     已开票，且已确认回款的项目数。
        if(role == 0 || role == 1 || role == 2 ){
            //所有项目
            List<ProjectInfo> allProject = projectInfoService.list();
            //预算待完成项目
            List<ProjectInfo> projectInfos = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .and(wrapper -> wrapper.eq("status",0).or().eq("status",1).or().eq("status",2)) );
            notBudgetNum=projectInfos.size();
            notBudgetNum=allProject.size()-notBudgetNum;
            //已审批预算项目
            List<ProjectInfo> projectInfos1 = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .and(wrapper -> wrapper.eq("status",3).or().eq("status",4).
                                        or().eq("status",5).or().eq("status",6)));
            for (ProjectInfo projectInfo : projectInfos1){
                ProjectEvalution projectEvalution = projectEvalutionService.getOne(new QueryWrapper<ProjectEvalution>().eq("project_id",projectInfo.getId()));
                if (projectEvalution == null){
                    notEvalutionNum++;
                }
                List<Invoice> invoices = invoiceService.list(new QueryWrapper<Invoice>().eq("project_id",projectInfo.getId()));
                if(invoices!=null && invoices.size()>0){
                    invoiceNum++;
                    for (Invoice invoice : invoices){
                        if(invoice.getPaymentCollectionTime()!=null){
                            backNum++;
                            break;
                        }
                    }
                }
            }
            evalutuionNum = projectInfos1.size()-notEvalutionNum;
            notInvoiceNum = projectInfos1.size()-invoiceNum;
            //报销待完成项目
            List<ProjectInfo> projectInfos2 = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .and(wrapper -> wrapper.eq("status",3).or().eq("status",4).or().eq("status",6)));
            notReimbursementNum = projectInfos2.size();
            reimbursementNum = projectInfos1.size() - notReimbursementNum;
            notBackNum = invoiceNum - backNum;

        }else if(role == 3){
            //所有项目
            List<ProjectInfo> allProject = projectInfoService.list();
            //预算待完成项目
            List<ProjectInfo> projectInfos = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .and(wrapper -> wrapper.eq("accound_id",accountId).or().eq("auxiliaryAccountId",accountId))
                    .and(wrapper -> wrapper.eq("status",0).or().eq("status",1).or().eq("status",2)) );
            notBudgetNum=projectInfos.size();
            notBudgetNum=allProject.size()-notBudgetNum;
            //已审批预算项目
            List<ProjectInfo> projectInfos1 = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .and(wrapper -> wrapper.eq("accound_id",accountId).or().eq("auxiliaryAccountId",accountId))
                    .and(wrapper -> wrapper.eq("status",3).or().eq("status",4).
                                    or().eq("status",5).or().eq("status",6)));
            for (ProjectInfo projectInfo : projectInfos1){
                ProjectEvalution projectEvalution = projectEvalutionService.getOne(new QueryWrapper<ProjectEvalution>().eq("project_id",projectInfo.getId()));
                if (projectEvalution == null){
                    notEvalutionNum++;
                }
                List<Invoice> invoices = invoiceService.list(new QueryWrapper<Invoice>().eq("project_id",projectInfo.getId()));
                if(invoices!=null && invoices.size()>0){
                    invoiceNum++;
                    for (Invoice invoice : invoices){
                        if(invoice.getPaymentCollectionTime()!=null){
                            backNum++;
                            break;
                        }
                    }
                }
            }
            evalutuionNum = projectInfos1.size()-notEvalutionNum;
            notInvoiceNum = projectInfos1.size()-invoiceNum;
            //报销待完成项目
            List<ProjectInfo> projectInfos2 = projectInfoService.list(new QueryWrapper<ProjectInfo>()
                    .and(wrapper -> wrapper.eq("accound_id",accountId).or().eq("auxiliaryAccountId",accountId))
                    .and(wrapper -> wrapper.eq("status",3).or().eq("status",4).or().eq("status",6)));
            notReimbursementNum = projectInfos2.size();
            reimbursementNum = projectInfos1.size() - notReimbursementNum;
            notBackNum = invoiceNum - backNum;
        }

        map.put("notBudgetNum",notBudgetNum);
        map.put("budgetNum",budgetNum);
        map.put("notEvalutionNum",notEvalutionNum);
        map.put("evalutuionNum",evalutuionNum);
        map.put("notReimbursementNum",notReimbursementNum);
        map.put("reimbursementNum",reimbursementNum);
        map.put("notInvoiceNum",notInvoiceNum);
        map.put("invoiceNum",invoiceNum);
        map.put("notBackNum",notBackNum);
        map.put("backNum",backNum);
        return ResponseUtil.jsonSuccess(map);
    }


    public static void main(String[] args) {
//        SimpleDateFormat  sdf = new SimpleDateFormat("yyyy-MM-dd");
//        Date date = new Date();
//        System.out.println(sdf.format(date).substring(0,4));
    }
}
